package com.zh.mycommon.viewdata;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public final class PageData<T> {

    /**
     * 当前页号
     * 从1开始
     */
    private Integer num;
    /**
     * 页条数
     */
    private Integer size;

    /**
     * 总条数
     */
    private long total;
    /**
     * 数据list
     */
    private List<T> list;

    private PageData() {
    }

    public PageData(int num, int size, long total) {
        if (num < 1 || size < 1 || total < 0)
            throw new IllegalArgumentException("参数pageNum或pageSize值不能<1，recordTotal值不能<0");
        this.num = num;
        this.size = size;
        this.total = total;
    }

    /**
     * 生成一个PageData对象
     * 只含有分页元数据，而列表数据为空数据
     *
     * @param pageNum 页号
     * @param pageSize 页大小
     * @param recordTotal 总条数
     * @param <T> T
     * @return pageData
     */
    public static <T> PageData<T> of(int pageNum, int pageSize, long recordTotal) {
        return of(pageNum, pageSize, recordTotal, List.of());
    }

    /**
     * 生成一个PageData对象
     * 含有分页元数据，以及列表数据。对象生成后是不可变的
     *
     * @param pageNum 页号
     * @param pageSize 页大小
     * @param recordTotal 总条数
     * @param list 列表数据
     * @param <T> T
     * @return pageData
     */
    public static <T> PageData<T> of(int pageNum, int pageSize, long recordTotal, List<T> list) {
        PageData<T> pageData = new PageData<>(pageNum, pageSize, recordTotal);
        pageData.setList(Collections.unmodifiableList(list));
        return pageData;
    }


    /**
     * 对PageData的元素进行map操作
     *
     * @param convert map操作
     * @return pageData
     */
    public <V> PageData<V> map(Function<T, V> convert) {
        var list = this.getList().stream().map(convert).toList();
        return PageData.of(this.getNum(), this.getSize(), this.getTotal(), list);
    }

    public Integer getNum() {
        return num;
    }

    public Integer getSize() {
        return size;
    }

    public Integer getPageTotal() {
        return (int) ((total - 1) / size) + 1;
    }

    public long getTotal() {
        return total;
    }

    private void setList(List<T> list) {
        this.list = list;
    }

    public List<T> getList() {
        return list == null ? List.of() : list;
    }

}

